/*
 * @Description: 游戏控制器
 * @Author: Zhy
 * @Date: 2024-07-09 11:42:53
 * @LastEditTime: 2024-07-09 16:13:42
 * @LastEditors: Zhy
 */
import Snake from "./Snake";
import Food from "./Food";
import ScorePanel from "./ScorePanel";

export default class GameControl {
  snake: Snake;
  food: Food;
  scorePanel: ScorePanel;

  // 蛇的移动方向
  direction: string = "";
  // 游戏是否结束
  isGameOver: boolean = false;

  constructor() {
    this.snake = new Snake();
    this.food = new Food();
    this.scorePanel = new ScorePanel();

    this.init();
  }

  init() {
    // 绑定键盘事件
    document.addEventListener("keydown", this.keydownHandler.bind(this));
    // 通过 bind 方法将 this 绑定到 keydownHandler 函数中，这样可以保证函数内的 this 指向当前的 GameControl 对象

    this.move();
  }

  // 创建键盘按下的响应函数
  keydownHandler(event: KeyboardEvent) {
    // console.log(event.key);
    this.direction = event.key;
  }

  // 蛇的移动函数
  move() {
    let snakeX = this.snake.x;
    let snakeY = this.snake.y;

    switch (this.direction) {
      case "ArrowUp":
      case "Up":
        snakeY -= 10;
        break;
      case "ArrowDown":
      case "Down":
        snakeY += 10;
        break;
      case "ArrowLeft":
      case "Left":
        snakeX -= 10;
        break;
      case "ArrowRight":
      case "Right":
        snakeX += 10;
        break;
    }

    this.checkEat(snakeX, snakeY);

    try {
      this.snake.x = snakeX;
      this.snake.y = snakeY;
    } catch (error: any) {
      this.isGameOver = true;
      alert(error.message + "Game Over!");
      location.reload();
    }

    !this.isGameOver &&
      setTimeout(() => {
        this.move();
      }, 650 - this.scorePanel.level * 50);
  }

  /**
   * @description: 判断蛇是否吃到食物
   * @Author: Zhy
   * @Date: 2024-07-09 15:17:31
   * @return {*}
   * @param {number} x 蛇头的 x 坐标
   * @param {number} y 蛇头的 y 坐标
   */
  checkEat(x: number, y: number) {
    if (this.food.x === x && this.food.y === y) {
      this.food.changePosition(); /* 更新食物的位置 */
      this.scorePanel.addScore(); /* 增加分数 */
      this.snake.addBody(); /* 增加蛇身 */
    }
  }
}
